ResolvedMapRelation.java
package org.codefilarete.stalactite.engine.configurer.model;
import java.util.Map;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import org.codefilarete.reflection.ReadWritePropertyAccessPoint;
import org.codefilarete.stalactite.dsl.property.CascadeOptions.RelationMode;
import org.codefilarete.stalactite.engine.configurer.map.KeyValueRecord;
import org.codefilarete.stalactite.sql.ddl.structure.Column;
import org.codefilarete.stalactite.sql.ddl.structure.ForeignKey;
import org.codefilarete.stalactite.sql.ddl.structure.Table;
import org.codefilarete.stalactite.sql.result.BeanRelationFixer;
public class ResolvedMapRelation<SRC, SRCID, K, KID, V, VID, M extends Map<K, V>,
LEFTTABLE extends Table<LEFTTABLE>,
MAPTABLE extends Table<MAPTABLE>,
KTABLE extends Table<KTABLE>,
VTABLE extends Table<VTABLE>>
extends ComponentRelation<SRC, KeyValueRecord<K, V, SRCID>, M, LEFTTABLE, MAPTABLE, SRCID> {
private final Map<Column<LEFTTABLE, ?>, Column<MAPTABLE, ?>> primaryKeyForeignKeyColumnMapping;
@Nullable
private final EntryMemberMapping<K, MAPTABLE> keyMapping;
@Nullable
private final EntryMemberMapping<V, MAPTABLE> valueMapping;
@Nullable
private final MapMemberAsEntity<K, KID, MAPTABLE, KTABLE, ?> keyEntityDefinition;
@Nullable
private final MapMemberAsEntity<V, VID, MAPTABLE, VTABLE, ?> valueEntityDefinition;
public <X, Y> ResolvedMapRelation(ReadWritePropertyAccessPoint<SRC, M> accessor,
boolean fetchSeparately,
DirectRelationJoin<LEFTTABLE, MAPTABLE, SRCID> join,
BeanRelationFixer<SRC, KeyValueRecord<K, V, SRCID>> beanRelationFixer,
Supplier<M> componentFactory,
Map<Column<LEFTTABLE, ?>, Column<MAPTABLE, ?>> primaryKeyForeignKeyColumnMapping,
@Nullable EntryMemberMapping<X, MAPTABLE> keyMapping,
@Nullable EntryMemberMapping<Y, MAPTABLE> valueMapping,
@Nullable MapMemberAsEntity<K, KID, MAPTABLE, KTABLE, X> keyEntityDefinition,
@Nullable MapMemberAsEntity<V, VID, MAPTABLE, VTABLE, Y> valueEntityDefinition) {
// TODO: ALL shouldn't be used for RelationMode : we should extend another class or make the RelationMode not available by default in the super class
super(accessor, RelationMode.ALL, fetchSeparately, join, beanRelationFixer, componentFactory);
this.primaryKeyForeignKeyColumnMapping = primaryKeyForeignKeyColumnMapping;
this.keyMapping = (EntryMemberMapping<K, MAPTABLE>) keyMapping;
this.valueMapping = (EntryMemberMapping<V, MAPTABLE>) valueMapping;
this.keyEntityDefinition = keyEntityDefinition;
this.valueEntityDefinition = valueEntityDefinition;
}
@Override
public DirectRelationJoin<LEFTTABLE, MAPTABLE, SRCID> getJoin() {
return (DirectRelationJoin<LEFTTABLE, MAPTABLE, SRCID>) super.getJoin();
}
public Map<Column<LEFTTABLE, ?>, Column<MAPTABLE, ?>> getPrimaryKeyForeignKeyColumnMapping() {
return primaryKeyForeignKeyColumnMapping;
}
@Nullable
public EntryMemberMapping<K, MAPTABLE> getKeyMapping() {
return keyMapping;
}
@Nullable
public EntryMemberMapping<V, MAPTABLE> getValueMapping() {
return valueMapping;
}
@Nullable
public MapMemberAsEntity<K, KID, MAPTABLE, KTABLE, ?> getKeyEntityDefinition() {
return keyEntityDefinition;
}
@Nullable
public MapMemberAsEntity<V, VID, MAPTABLE, VTABLE, ?> getValueEntityDefinition() {
return valueEntityDefinition;
}
public interface EntryMemberMapping<X, MAPTABLE extends Table<MAPTABLE>> {
}
public static class ScalarMemberMapping<X, MAPTABLE extends Table<MAPTABLE>>
implements EntryMemberMapping<X, MAPTABLE> {
private final Column<MAPTABLE, X> column;
public ScalarMemberMapping(Column<MAPTABLE, X> column) {
this.column = column;
}
public Column<MAPTABLE, X> getColumn() {
return column;
}
}
public static class CompositeMemberMapping<XID, MAPTABLE extends Table<MAPTABLE>>
implements EntryMemberMapping<XID, MAPTABLE> {
private final Class<XID> beanType;
private final Map<ReadWritePropertyAccessPoint<XID, ?>, Column<MAPTABLE, ?>> mapping;
public CompositeMemberMapping(Class<XID> beanType, Map<ReadWritePropertyAccessPoint<XID, ?>, Column<MAPTABLE, ?>> mapping) {
this.beanType = beanType;
this.mapping = mapping;
}
public Class<XID> getBeanType() {
return beanType;
}
public Map<ReadWritePropertyAccessPoint<XID, ?>, Column<MAPTABLE, ?>> getMapping() {
return mapping;
}
}
public static class MapMemberAsEntity<ENTITY, ENTITY_ID, MAPTABLE extends Table<MAPTABLE>, ENTITY_TABLE extends Table<ENTITY_TABLE>, X /* is either ENTITY or ENTITY_ID */> {
private final ForeignKey<MAPTABLE, ENTITY_TABLE, ENTITY_ID> foreignKey;
private final Entity<ENTITY, ENTITY_ID, ENTITY_TABLE> entity;
private final RelationMode relationMode;
public MapMemberAsEntity(Entity<ENTITY, ENTITY_ID, ENTITY_TABLE> entity,
ForeignKey<MAPTABLE, ENTITY_TABLE, ENTITY_ID> foreignKey,
RelationMode relationMode) {
this.foreignKey = foreignKey;
this.entity = entity;
this.relationMode = relationMode;
}
public ForeignKey<MAPTABLE, ENTITY_TABLE, ENTITY_ID> getForeignKey() {
return foreignKey;
}
public Entity<ENTITY, ENTITY_ID, ENTITY_TABLE> getEntity() {
return entity;
}
public RelationMode getRelationMode() {
return relationMode;
}
}
}